package com.genius.Genius.Element.String;

import java.util.Arrays;
import java.util.Optional;

public class Gstring {
    private int length;
    private int buffer;
    private char[] chs;

    private final static int DEFAULT_STRING_SIZE = 2;
    private final static int INIT_LIMIT = 10000;
    private final static int RESIZE_LIMIT = 1024*1024;
    private final static int KB_ARRAY_SIZE = 512;

    public Gstring(){
        this.length = 0;
        this.buffer = DEFAULT_STRING_SIZE*2;
        this.chs = new char[DEFAULT_STRING_SIZE];
    }

    public Gstring(String str){
        if(Optional.ofNullable(str).isEmpty()){
            this.length = 0;
            this.chs = new char[DEFAULT_STRING_SIZE];
            ensureBuffer();

        }else {
            int length = str.length();
            this.chs = new char[length];
            ensureBuffer();
            if (length > INIT_LIMIT) {
                StringUtil.stringToChars(str, this.chs);
            } else {
                StringUtil.stringToCharsByStream(str, this.chs);
            }
        }
    }

    public int append(String str){
        if(Optional.ofNullable(str).isEmpty()||length==Integer.MAX_VALUE){
            return -1;
        }
        int n = str.length();
        int nowBuffer = (length+n)*2;
        if(buffer<nowBuffer){
            chs = Arrays.copyOf(chs,nowBuffer);
        }
        System.arraycopy(str.toCharArray(),0,chs,length,n);
        length+=n;
        ensureBuffer();
        return length;
    }

    private void ensureBuffer(){
        buffer = chs.length*2;
    }

    @Override
    public String toString() {
        return String.copyValueOf(chs);
    }

    public static void main(String[] args) {
        StackTraceElement[] stack = new Throwable().getStackTrace();
        System.out.println(stack[stack.length - 1].getClassName());
    }

}
